using B.S.Requst;
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using B.S.Domain.InvoiceManagement;
using B.S.Infratrctrue;
using B.S.Data.MES.API.Dto.InvoiceDTO;
using Microsoft.EntityFrameworkCore;

namespace B.S.Data.MES.API.Applications.B.S.KApplications.Query.InvoiceReceiptQuery
{
    /// <summary>
    /// 获取到票列表查询处理程序
    /// 处理到票信息的列表查询逻辑
    /// </summary>
    public class GetInvoiceReceiptQueryHandler : IRequestHandler<GetInvoiceReceiptQuery, APIRequst<APIPageing<List<InvoiceReceiptDTO>>>>
    {
        private readonly IBaseRepository<InvoiceReceipt> _invoiceReceiptRepository;
        private readonly IBaseRepository<SalesInvoice> _salesInvoiceRepository;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="invoiceReceiptRepository">到票仓储</param>
        /// <param name="salesInvoiceRepository">销售发票仓储</param>
        public GetInvoiceReceiptQueryHandler(
            IBaseRepository<InvoiceReceipt> invoiceReceiptRepository,
            IBaseRepository<SalesInvoice> salesInvoiceRepository)
        {
            _invoiceReceiptRepository = invoiceReceiptRepository;
            _salesInvoiceRepository = salesInvoiceRepository;
        }

        /// <summary>
        /// 处理获取到票列表的查询
        /// </summary>
        /// <param name="request">获取到票列表查询请求</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>处理结果，包含分页的到票列表</returns>
        public async Task<APIRequst<APIPageing<List<InvoiceReceiptDTO>>>> Handle(GetInvoiceReceiptQuery request, CancellationToken cancellationToken)
        {
            try
            {
                // 构建查询
                 var query = _invoiceReceiptRepository.GetAll()
                    .Where(s => !s.isDel); // 排除已删除的记录

                // 按发票ID过滤
                if (request.InvoiceId > 0)
                {
                    query = query.Where(s => s.InvoiceId == request.InvoiceId);
                }

                // 按关键词过滤
                if (!string.IsNullOrEmpty(request.Keyword))
                {
                    // 获取符合关键词的发票ID列表
                    var invoiceIds = _salesInvoiceRepository.GetAll()
                        .Where(i => !i.isDel && i.InvoiceNo.Contains(request.Keyword))
                        .Select(i => i.InvoiceId)
                        .ToList();

                    // 过滤到票记录
                    query = query.Where(s => 
                        s.PaymentMethod.Contains(request.Keyword) || 
                        s.TransactionNo.Contains(request.Keyword) ||
                        s.Remarks.Contains(request.Keyword) ||
                        invoiceIds.Contains(s.InvoiceId));
                }

                // 按到票状态过滤
                if (request.ReceiptStatus > 0 && request.ReceiptStatus <= 2)
                {
                    query = query.Where(s => s.ReceiptStatus == request.ReceiptStatus);
                }

                // 按日期范围过滤
                if (request.StartDate.HasValue)
                {
                    query = query.Where(s => s.ReceiptDate >= request.StartDate.Value.Date);
                }
                if (request.EndDate.HasValue)
                {
                    query = query.Where(s => s.ReceiptDate <= request.EndDate.Value.Date.AddDays(1).AddMilliseconds(-1));
                }

                // 计算总记录数
                int totalCount = await query.CountAsync(cancellationToken);

                // 计算总页数
                int totalPage = (totalCount + request.PageSize - 1) / request.PageSize;

                // 执行分页查询
                var invoiceReceipts = await query
                    .OrderByDescending(s => s.ReceiptId)
                    .Skip((request.PageIndex - 1) * request.PageSize)
                    .Take(request.PageSize)
                    .ToListAsync(cancellationToken);

                // 获取相关的发票信息
                var invoiceIdsList = invoiceReceipts.Select(s => s.InvoiceId).Distinct().ToList();
                var invoices = await _salesInvoiceRepository.GetAll().Where(i => invoiceIdsList.Contains(i.InvoiceId) && !i.isDel).ToListAsync();
                var invoiceDict = invoices.ToDictionary(i => i.InvoiceId, i => i);

                // 转换为DTO列表
                var invoiceReceiptDTOs = new List<InvoiceReceiptDTO>();
                foreach (var receipt in invoiceReceipts)
                {
                    var dto = new InvoiceReceiptDTO
                    {
                        ReceiptId = receipt.ReceiptId,
                        InvoiceId = receipt.InvoiceId,
                        InvoiceNo = invoiceDict.ContainsKey(receipt.InvoiceId) ? invoiceDict[receipt.InvoiceId].InvoiceNo : string.Empty,
                        ReceiptDate = receipt.ReceiptDate,
                        ReceiptAmount = receipt.ReceiptAmount,
                        ReceiptStatus = receipt.ReceiptStatus,
                        ReceiptStatusName = GetReceiptStatusName(receipt.ReceiptStatus),
                        PaymentMethod = receipt.PaymentMethod,
                        TransactionNo = receipt.TransactionNo,
                        Remarks = receipt.Remarks,
                        CreateName = receipt.CreateName,
                        CreateTime = receipt.CreateTime ?? DateTime.Now,
                        UpdateName = receipt.UpdateName,
                        UpdateTime = receipt.UpdateTime ?? DateTime.Now
                    };

                    invoiceReceiptDTOs.Add(dto);
                }

                // 构建分页结果
                var pageResult = new APIPageing<List<InvoiceReceiptDTO>>
                {
                    Total = totalPage,
                    TotalCount = totalCount,
                    Data = invoiceReceiptDTOs
                };

                return new APIRequst<APIPageing<List<InvoiceReceiptDTO>>>
                {
                    Code = RequstCode.成功,
                    Msg = "查询成功",
                    Data = pageResult
                };
            }
            catch (Exception ex)
            {
                // 记录异常并返回失败结果
                return new APIRequst<APIPageing<List<InvoiceReceiptDTO>>>
                {
                    Code = RequstCode.失败,
                    Msg = $"查询失败：{ex.Message}"
                };
            }
        }

        /// <summary>
        /// 获取到票状态名称
        /// </summary>
        /// <param name="status">到票状态值</param>
        /// <returns>到票状态名称</returns>
        private string GetReceiptStatusName(int status)
        {
            switch (status)
            {
                case 0:
                    return "部分到票";
                case 1:
                    return "全部到票";
                case 2:
                    return "未到票";
                default:
                    return "未知";
            }
        }
    }
}